www.gusucode.com > C++ 利用MAP和VECTOR实现多节点树-源码程序 > C++ 利用MAP和VECTOR实现多节点树-源码程序/code/tree.cpp
//Download by http://www.NewXing.com #ifndef _TREE_H_ #define _TREE_H_ /* Copyright - All copy right is owned by Mr Jack Hui Author : Jack, Hui Ho Yin Email : jackhui@hotmail.com Last Update : 27-Aug-2000 */ #pragma warning(disable : 4786) //debug info - name too long #include <vector> #include <map> #include <string> #include <iostream> using namespace std; namespace Tiffany { //forward declarations template <class Key, class T> class TreeNode; template <class Key, class T> class Tree; template <class Key, class T> class Tree_iterator; // template <class Key, class T> class TreeNode { public: T m_data; //things stored in treenode Key m_key; //key to locate myself int m_level; //rootnode is of level 1 TreeNode<Key,T>* m_parent; //points to node of parent vector<TreeNode<Key,T> *> m_children; //holds pointers for children vector<TreeNode<Key,T> *>::iterator m_current; //holds iterator to current child processing Tree<Key, T>* m_LinkedTree; //whom i'm belonging to TreeNode(Tree<Key,T>* tr) : m_parent(NULL) { m_LinkedTree = tr; }; TreeNode(Tree<Key,T>* tr, const Key key, const T x) { m_key = key; m_data = x; m_LinkedTree = tr; }; //Delete all the children of this node including all the down levels void DeleteAllChildren() { vector<TreeNode<Key,T>*>::iterator pchild; map<Key, TreeNode<Key,T>*>::iterator itrmap; for(pchild=m_children.begin();pchild != m_children.end();) { (*pchild)->DeleteAllChildren(); itrmap = m_LinkedTree->m_nodemap.find((*pchild)->m_key); m_LinkedTree->m_nodemap.erase(itrmap); delete *pchild; m_children.erase(pchild); //after removing the node, iterater is advanced } }; //Return a reference to parent node in the tree TreeNode<Key,T>& GetParent () const { return *m_parent; }; //returns a reference to vector to the children const vector<TreeNode<Key,T>*>& GetChildren () const { return m_children; }; long ChildCount () const { return m_children.size(); }; //add a child node to this node void AddChild (TreeNode<Key,T>* child) { child->m_parent = this; child->m_level = this->m_level + 1; m_children.push_back(child); }; T GetData(void) const { return m_data; } }; //************ End of Tree Node declaration ***************************// // //************ Start of Tree declaration ***************************// // template <class Key, class T> class Tree { friend class TreeNode<Key, T>; protected: //provide a name of the TreeNode to direct access to it map<Key, TreeNode<Key,T>*> m_nodemap; //a map for fast accessing TreeNode TreeNode<Key,T>* m_pTreeroot; //a pointer to root node TreeNode<Key,T>* m_WalkPivot; //Sub-tree root for walking TreeNode<Key,T>* m_WalkCurrent; //point to current node of walking TreeNode<Key,T>* m_WalkParent; //point to parent node of current node public: typedef Tree_iterator<Key, T> iterator; typedef const iterator const_iterator; iterator begin() { iterator _tmp; _tmp.m_Node = m_nodemap.begin(); return _tmp; } iterator end() { iterator _tmp; _tmp.m_Node = m_nodemap.end(); return _tmp; } const_iterator begin() const { iterator _tmp; _tmp.m_Node = m_nodemap.begin(); return _tmp; } const_iterator end() const { const_iterator _tmp; _tmp.m_Node = m_nodemap.end(); return _tmp; } iterator find(const Key& key) { iterator _tmp; _tmp.m_Node = m_nodemap.find(key); return _tmp; } const_iterator find(const Key& key) const { const_iterator _tmp; _tmp.m_Node = m_nodemap.find(key); return _tmp; } Tree () : m_pTreeroot(NULL) { //instantiate an empty tree } Tree (const Key nm, const T x) { //instantiate a tree with the root node TreeNode<Key,T>* pNode; pNode = new TreeNode<Key,T>(this, nm, x); m_nodemap.insert(map<Key, TreeNode<Key,T>*>::value_type(nm, pNode)); m_pTreeroot = pNode; pNode->m_level = 1; } ~Tree() { if (m_pTreeroot) { m_pTreeroot->DeleteAllChildren(); delete m_pTreeroot; } } //returns tree root node, or NULL for empty tree TreeNode<Key,T>& GetRoot () const { return *m_pTreeroot; } iterator AddChild (iterator& parent, const Key nm, const T x) { TreeNode<Key,T>* pNew; pNew = new TreeNode<Key,T>(this, nm, x); parent.m_Node->second->AddChild(pNew); pair<map<Key, TreeNode<Key,T>*>::iterator, bool> pt = m_nodemap.insert(map<Key, TreeNode<Key,T>*>::value_type(nm, pNew)); iterator _tmp; _tmp.m_Node = pt.first; return _tmp; } iterator AddChild (const Key nm, const T x) { TreeNode<Key,T>* pNew; pNew = new TreeNode<Key,T>(this, nm, x); m_pTreeroot->AddChild(pNew); pair<map<Key, TreeNode<Key,T>*>::iterator, bool> pt = m_nodemap.insert(map<Key, TreeNode<Key,T>*>::value_type(nm, pNew)); iterator _tmp; _tmp.m_Node = pt.first; return _tmp; } void DeleteAllChildren(iterator & itr) { itr.m_Node->second->DeleteAllChildren(); } size_t size(void) { return m_nodemap.size(); } //Set the sub-tree walking root and traverse to the first node void SetPostOrderSubTreePivot(iterator& it) { m_WalkPivot = it.m_Node->second; m_WalkCurrent = m_WalkPivot; m_WalkCurrent->m_current = m_WalkCurrent->m_children.begin(); while (m_WalkCurrent->m_children.size() != 0) { m_WalkCurrent->m_current = m_WalkCurrent->m_children.begin(); m_WalkCurrent = *(m_WalkCurrent->m_children.begin()); } if (m_WalkCurrent != m_WalkPivot) { m_WalkParent = m_WalkCurrent->m_parent; } else { m_WalkParent = m_WalkCurrent; //for the case no child in pivot } } //Set the sub-tree walking root and traverse to the first node void SetPostOrderRootPivot() { m_WalkPivot = m_pTreeroot; m_WalkCurrent = m_WalkPivot; m_WalkCurrent->m_current = m_WalkCurrent->m_children.begin(); while (m_WalkCurrent->m_children.size() != 0) { m_WalkCurrent->m_current = m_WalkCurrent->m_children.begin(); m_WalkCurrent = *(m_WalkCurrent->m_children.begin()); } if (m_WalkCurrent != m_WalkPivot) { m_WalkParent = m_WalkCurrent->m_parent; } else { m_WalkParent = m_WalkCurrent; //for the case no child in pivot } } void SetWalkDownRootPivot() { m_WalkPivot = m_pTreeroot; m_WalkCurrent = m_WalkPivot; m_WalkCurrent->m_current = m_WalkCurrent->m_children.begin(); } //it advances m_WalkCurrent in post-order, and returns true if a move is made //else it returns false bool SubTreePostOrderWalk() { if (m_WalkCurrent == m_WalkPivot) return false; //if not the parent's last child, advance one node in paraent's child //if the advanced child contains sub node, go in depth to the leftmost one if (++m_WalkParent->m_current != m_WalkParent->m_children.end()) { m_WalkCurrent = *(m_WalkParent->m_current); while (m_WalkCurrent->m_children.size() != 0) { //go down m_WalkCurrent->m_current = m_WalkCurrent->m_children.begin(); m_WalkParent = m_WalkCurrent; m_WalkCurrent = *(m_WalkCurrent->m_current); } } else { //if it's the last child of parent, we go up m_WalkCurrent = m_WalkParent; m_WalkParent = m_WalkCurrent->m_parent; } m_WalkParent = m_WalkCurrent->m_parent; return true; } //It advance the tree in top-down style with parent first bool SubTreeWalkDown() { //if it has children, we go down to children if (m_WalkCurrent->m_current != m_WalkCurrent->m_children.end()) { m_WalkCurrent = *(m_WalkCurrent->m_current); m_WalkParent = m_WalkCurrent->m_parent; m_WalkParent->m_current++; //advance to next child for next iteration m_WalkCurrent->m_current = m_WalkCurrent->m_children.begin(); //initialize to first child } else { //if it's the last child of parent, we go up to the level //which we still need processing by recurively call ourself if (m_WalkCurrent == m_WalkPivot) return false; //no more child m_WalkCurrent = m_WalkCurrent->m_parent; m_WalkParent = m_WalkCurrent->m_parent; SubTreeWalkDown(); } return true; } void DelSubTree() { } T SubTreeGetData(void) { return m_WalkCurrent->m_data; } T SubTreeGetLevel(void) { return m_WalkCurrent->m_level; } }; //class Tree //************ End of Tree declaration ***************************// // template <class Key, class T> class Tree_iterator { typedef map<Key, TreeNode<Key,T>*>::iterator _map_it; public: _map_it m_Node; T operator*() const { return (m_Node->second)->GetData(); } Tree_iterator& operator++() { m_Node++; return *this; } Tree_iterator operator++(int) { Tree_iterator __tmp = *this; m_Node++; return __tmp; } Tree_iterator& operator--() { m_Node--; return *this; } bool operator==(const Tree_iterator& _y) const { return m_Node == _y.m_Node; } bool operator!=(const Tree_iterator& _y) const { return m_Node != _y.m_Node; } }; //class Tree_iterator }; //namespace Tiffany #endif //_TREE_H_